import axios from 'axios'
import router from '@/router'
import store from '@/store'

// 创建axios实例
const request = axios.create({
  baseURL: process.env.VUE_APP_API_URL || 'http://localhost:8080',
  timeout: 10000
})

// 用于存储正在刷新的token请求
let isRefreshing = false
let failedQueue = []

// 处理队列中的请求
const processQueue = (error, token = null) => {
  failedQueue.forEach(prom => {
    if (error) {
      prom.reject(error)
    } else {
      prom.resolve(token)
    }
  })
  
  failedQueue = []
}

// 请求拦截器
request.interceptors.request.use(
  config => {
    // 添加token到请求头
    const token = localStorage.getItem('accessToken')
    console.log('请求拦截器 - 请求URL:', config.url)
    console.log('请求拦截器 - token:', token ? '存在' : '不存在')
    
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
      console.log('请求拦截器 - 已添加Authorization头')
    } else {
      console.log('请求拦截器 - 未添加Authorization头')
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器
request.interceptors.response.use(
  response => {
    const { data } = response
    console.log('响应拦截器 - 原始响应:', data)
    
    // 如果响应成功，直接返回data字段
    if (data.code === 0) {
      console.log('响应拦截器 - 返回data字段:', data.data)
      return data.data
    }
    
    // 处理业务错误
    if (data.code === 401) {
      // token过期，尝试刷新
      console.log('业务错误401 - 检测到token过期')
      return handleTokenExpired().then(result => {
        if (result.refreshed) {
          console.log('业务错误401 - token刷新成功，需要重新发起原请求')
          // 这里需要重新发起原请求，但由于axios拦截器的限制，
          // 我们需要在业务代码中处理，或者抛出特殊错误让调用方处理
          return Promise.reject(new Error('TOKEN_REFRESHED'))
        }
        return result
      })
    }
    
    // 其他业务错误
    return Promise.reject(new Error(data.msg || '请求失败'))
  },
  error => {
    const originalRequest = error.config
    
    if (error.response) {
      const { status, data } = error.response
      
      switch (status) {
        case 401:
          // 未授权，尝试刷新token
          console.log('HTTP错误401 - 检测到token过期')
          if (originalRequest._retry) {
            // 已经重试过了，直接跳转登录页
            console.log('token刷新失败，跳转登录页')
            clearAuthData()
            router.push('/login')
            return Promise.reject(error)
          }
          
          if (isRefreshing) {
            // 正在刷新token，将请求加入队列
            return new Promise((resolve, reject) => {
              failedQueue.push({ resolve, reject })
            }).then(token => {
              originalRequest.headers.Authorization = `Bearer ${token}`
              return request(originalRequest)
            }).catch(err => {
              return Promise.reject(err)
            })
          }
          
          originalRequest._retry = true
          isRefreshing = true
          
          return refreshTokenAndRetry(originalRequest)
          
        case 403:
          // 无权限
          console.error('无权限访问')
          break
        case 404:
          console.error('请求的资源不存在')
          break
        case 500:
          console.error('服务器内部错误')
          break
        default:
          console.error('请求失败:', (data && data.msg) || error.message)
      }
    } else if (error.message === 'TOKEN_REFRESHED') {
      // token已刷新，需要重新发起原请求
      console.log('检测到token已刷新，需要重新发起请求')
      return Promise.reject(error)
    } else {
      console.error('网络错误:', error.message)
    }
    
    return Promise.reject(error)
  }
)

/**
 * 处理业务错误401 - token过期
 */
async function handleTokenExpired() {
  const refreshToken = localStorage.getItem('refreshToken')
  
  if (!refreshToken) {
    console.log('业务错误401 - 没有refreshToken，跳转登录页')
    clearAuthData()
    router.push('/login')
    return Promise.reject(new Error('请重新登录'))
  }
  
  try {
    console.log('业务错误401 - 开始刷新token...')
    
    // 创建新的axios实例来刷新token
    const refreshAxios = axios.create({
      baseURL: process.env.VUE_APP_API_URL || 'http://localhost:8080',
      timeout: 10000
    })
    
    const response = await refreshAxios.post('/api/v1/auth/refresh', {
      refreshToken
    })
    
    console.log('业务错误401 - 刷新token响应:', response.data)
    
    if (response.data.code === 0 && response.data.data.accessToken) {
      const { accessToken, refreshToken: newRefreshToken } = response.data.data
      
      // 更新token
      localStorage.setItem('accessToken', accessToken)
      localStorage.setItem('refreshToken', newRefreshToken)
      store.commit('setToken', accessToken)
      
      console.log('业务错误401 - token刷新成功')
      
      // 返回成功，让调用方知道token已刷新
      return { refreshed: true, accessToken }
      
    } else {
      console.error('业务错误401 - 刷新token响应数据无效:', response.data)
      clearAuthData()
      router.push('/login')
      return Promise.reject(new Error('刷新token失败'))
    }
    
  } catch (error) {
    console.error('业务错误401 - 刷新token失败:', error)
    clearAuthData()
    router.push('/login')
    return Promise.reject(new Error('刷新token失败'))
  }
}

/**
 * 刷新token并重试原请求
 */
async function refreshTokenAndRetry(originalRequest) {
  const refreshToken = localStorage.getItem('refreshToken')
  
  if (!refreshToken) {
    console.log('没有refreshToken，跳转登录页')
    clearAuthData()
    router.push('/login')
    processQueue(new Error('没有refreshToken'))
    return Promise.reject(new Error('请重新登录'))
  }
  
  try {
    console.log('开始刷新token...')
    
    // 创建新的axios实例来刷新token，避免循环调用
    const refreshAxios = axios.create({
      baseURL: process.env.VUE_APP_API_URL || 'http://localhost:8080',
      timeout: 10000
    })
    
    const response = await refreshAxios.post('/api/v1/auth/refresh', {
      refreshToken
    })
    
    console.log('刷新token响应:', response.data)
    
    if (response.data.code === 0 && response.data.data.accessToken) {
      const { accessToken, refreshToken: newRefreshToken } = response.data.data
      
      // 更新token
      localStorage.setItem('accessToken', accessToken)
      localStorage.setItem('refreshToken', newRefreshToken)
      store.commit('setToken', accessToken)
      
      console.log('token刷新成功，重试原请求')
      
      // 处理队列中的请求
      processQueue(null, accessToken)
      
      // 重试原请求
      originalRequest.headers.Authorization = `Bearer ${accessToken}`
      return request(originalRequest)
      
    } else {
      console.error('刷新token响应数据无效:', response.data)
      clearAuthData()
      router.push('/login')
      processQueue(new Error('刷新token失败'))
      return Promise.reject(new Error('刷新token失败'))
    }
    
  } catch (error) {
    console.error('刷新token失败:', error)
    clearAuthData()
    router.push('/login')
    processQueue(error)
    return Promise.reject(error)
  } finally {
    isRefreshing = false
  }
}

/**
 * 清除认证数据
 */
function clearAuthData() {
  localStorage.removeItem('accessToken')
  localStorage.removeItem('refreshToken')
  store.commit('clearUserInfo')
  store.commit('clearToken')
}

/**
 * 登录接口
 * @param {Object} data 登录参数
 * @returns {Promise}
 */
export function login(data) {
  return request.post('/api/v1/auth/login', data)
}

/**
 * 刷新token接口
 * @param {Object} data 刷新token参数
 * @returns {Promise}
 */
export function refreshToken(data) {
  return request.post('/api/v1/auth/refresh', data)
}

/**
 * 登出接口
 * @returns {Promise}
 */
export function logout() {
  return request.post('/api/v1/auth/logout')
}

/**
 * 获取当前用户信息
 * @returns {Promise}
 */
export function getCurrentUser() {
  return request.get('/api/v1/users/me')
}

// 导出request实例，用于其他API调用
export default request
